package com.zwcl.glass.tools.service.impl;

import com.zwcl.common.core.exception.BaseException;
import com.zwcl.common.core.exception.BusinessException;
import com.zwcl.common.core.utils.JsonUtils;
import com.zwcl.glass.tools.entity.*;
import com.zwcl.glass.tools.service.RuleHandlerService;
import com.zwcl.glass.tools.utils.CartesianArith;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class RuleHandlerServiceImpl implements RuleHandlerService {

    /**
     * 传入有效的规则
     * 根据答题的结果，推导出结论
     * 先处理复合规则，再处理简单规则
     * @param answerResults
     * @param conclusionRules
     * @return
     */
    @Override
    public List<String> generateConclusion(List<AnswerResultHanlder> answerResults, List<ConclusionRule> conclusionRules) {
        log.info("用户答案：{}", JsonUtils.objectToJson(answerResults));
        log.info("结论规则：{}", JsonUtils.objectToJson(conclusionRules));
        //返回迪卡尔积和规则id的map
        Map<String,Integer> ruleKeys= buildConclusionRuleKeys(conclusionRules);
        Map<String,String> answerKeys=buildAnswerKeys(answerResults);
        Set<Integer> conclusionResultIds=new HashSet<>();
        for(Map.Entry<String,Integer> item : ruleKeys.entrySet()){
            String rule=item.getKey();
            String[] ruleKeyArr=rule.split("\\|");
            Boolean succFlag=true;
            for (int i=0;i<ruleKeyArr.length;i++){
                if(!answerKeys.containsKey(ruleKeyArr[i])){               //不存在这个答案
                    succFlag=false;
                }
            }
            if(succFlag){
                conclusionResultIds.add(item.getValue());
            }
        }
        //形成最终的结论，有可能结论需要根据类别，以及优先级进行删除重复的。
        //Map<Integer,String> conclusionRuleMap= conclusionRules.stream().collect(Collectors.toMap(p->p.getId(),p->p.getConclusionContent()));
        //List<String> conclusionResult= conclusionRuleMap.entrySet().stream().filter(x->conclusionResultIds.contains(x.getKey())).map(x->x.getValue()).collect(Collectors.toList());
        //去除同类型的结论
        List<String> conclusionResult=conclusionRules.stream().filter(x->conclusionResultIds.contains(x.getId())).map(x->x.getConclusionContent()).collect(Collectors.toList());
        log.info(StringUtils.join(conclusionResult,","));
        return conclusionResult;
    }

    /**
     * 注意，新规则体系，有可能是选项规则和值范围规则进行复合
     * OptionRules  ValueRules  ShowRules
     * @param answerResults
     * @param conclusionRules
     * @return
     */
    @Override
    public Map<String,List<String>> generateConclusionEx(List<AnswerResultHanlder> answerResults, List<ConclusionRuleEx> conclusionRules) {
        log.info("用户答案：{}", JsonUtils.objectToJson(answerResults));
        log.info("结论规则：{}", JsonUtils.objectToJson(conclusionRules));
        Map<Integer,ConclusionRuleEx> conclusionRuleMap=conclusionRules.stream().collect(Collectors.toMap(x->x.getId(),y->y));
        Map<String,Object> ruleMap=buildConclusionRuleKeysEx(conclusionRules);
        //新修改，从规则开始，要变化;老规则返回迪卡尔积和规则id的map，比如：Map<"1#C|2#D",300>
        Map<String,Integer> optionRuleMap= (Map<String,Integer>) ruleMap.get("OptionRules");  //buildConclusionOptionRuleKeys(conclusionRules);
        //Map<规则id,范围规则列表>
        Map<Integer,List<ValueRule>>  valueRuleMap=(Map<Integer,List<ValueRule>>)ruleMap.get("ValueRules"); //buildConclusionValueRuleKeys(conclusionRules);
        //老规则返回 Map<"1#C",C>，比较老规则的笛卡尔积
        Map<String,String> optionAnswerKeys= buildAnswerOptionKeys(answerResults);
        //新的答案统计数据，格式Map<题号，统计数>
        Map<Integer,Double> valueAnswerKeys=buildAnswerValueKeys(answerResults);
        Set<Integer> conclusionResultIds=new HashSet<>();
        //如果有选项规则
        //兼容OptionRule一定有，但是ValueRule不一定有的情况，有的情况下，也是和optionRule一起生效
        Set<Integer> needExcludeValueRulesIds=new HashSet<>();
        if(null!=optionRuleMap && optionRuleMap.size()>0) {
            //循环选项规则的map，和用户的答案匹配
            for(Map.Entry<String,Integer> item : optionRuleMap.entrySet()) {
                String rule = item.getKey();
                String[] ruleKeyArr = rule.split("\\|");
                Boolean optionSuccFlag = true;
                for (int i = 0; i < ruleKeyArr.length; i++) {
                    if (!optionAnswerKeys.containsKey(ruleKeyArr[i])) {               //不存在这个答案
                        optionSuccFlag = false;
                    }
                }
                Boolean valueSuccFlag = true;
                if (optionSuccFlag) {    //如果满足笛卡尔积的规则
                    //再校验，该结论id是否还有范围规则
                    if (null!=valueRuleMap && valueRuleMap.containsKey(item.getValue())) {
                        needExcludeValueRulesIds.add(item.getValue());   //某个结论同时具备选项规则和值范围规则，后面需要排除的规则id
                        //校验所有的范围规则是否满足
                        valueSuccFlag = verifyValueRule(valueRuleMap.get(item.getValue()), valueAnswerKeys);
                    }
                }
                //两项规则都满足
                if(optionSuccFlag && valueSuccFlag){
                    conclusionResultIds.add(item.getValue());   //加入该结论的id
                }
            }
        }
        //使用下面的判断，需要清除掉已经用过的值范围规则（有可能在上面已经用过）
        //TODO:这里还有bug,也有可能仅有value规则,如果
        if (null!=valueRuleMap && valueRuleMap.size()>0){
            //遍历值范围规则
            for (Map.Entry<Integer, List<ValueRule>> item : valueRuleMap.entrySet()) {
                //有些值范围规则是独立的，没有在上面被使用过
                if(!needExcludeValueRulesIds.contains(item.getKey())) {
                    //校验该结论下所有的范围规则是否满足
                    Boolean valueSuccFlag = verifyValueRule(item.getValue(), valueAnswerKeys);
                    if (valueSuccFlag) {
                        conclusionResultIds.add(item.getKey());   //加入该结论的id
                    }
                }
            }
        }
        //值直接展示的规则，Map<规则id，problemIds>
        Map<Integer,List<Integer>>  showRuleMap= (Map<Integer,List<Integer>>) ruleMap.get("ShowRules"); //buildConclusionShowRuleKeys(conclusionRules);
        //有匹配上值显示规则
        List<String> showConclusionList=new ArrayList<>();
        if(null!=showRuleMap && showRuleMap.size()>0){
            Map<Integer,String[]> showKeysMap = buildAnswerShowKeys(answerResults);
            showConclusionList = deduceShowRuleConclusion(showRuleMap,showKeysMap,conclusionRuleMap);
        }

        //去除同类型的结论
        //获取结论，且获取用户标签
        Map<String,List<String>> resultAndTagsMap= generateConclusionResult(conclusionResultIds,conclusionRuleMap,showConclusionList);
        return resultAndTagsMap;
    }

    /**
     * 根据结论id，生成结论或者用户标签
     * @return
     */
    public Map<String,List<String>> generateConclusionResult(Set<Integer> conclusionResultIds,Map<Integer,ConclusionRuleEx> conclusionRuleMap,List<String> showConclusionList){
        //去除同类型的结论
        //获取结论，且获取用户标签
        Map<String,String> conclusionResultMap=new HashMap<>();
        Map<String,String> conclusionTagsMap=new HashMap<>();
        for(Integer conclusionId : conclusionResultIds){
            ConclusionRuleEx conclusionRule = conclusionRuleMap.get(conclusionId);
            //加入结论
            if(StringUtils.isNotBlank(conclusionRule.getConclusionContent())){
                conclusionResultMap.put(conclusionRule.getTypeCode(),conclusionRule.getConclusionContent());
            }
            //加入标签
            if(StringUtils.isNotBlank(conclusionRule.getConclusionTags())){
                conclusionTagsMap.put(conclusionRule.getTypeCode(),conclusionRule.getConclusionTags());
            }
        }
        List<String> conclusionResult = conclusionResultMap.entrySet().stream().map(x -> x.getValue()).collect(Collectors.toList());
        //添加直接显示的那种规则
        conclusionResult.addAll(showConclusionList);

        List<String> conclusionTags = conclusionTagsMap.entrySet().stream().map(x -> x.getValue()).distinct().collect(Collectors.toList());
        log.info(StringUtils.join(conclusionResult,","));
        Map<String,List<String>> resultAndTagsMap=new HashMap<>();
        resultAndTagsMap.put("conclusion",conclusionResult);
        resultAndTagsMap.put("tags",conclusionTags);
        return resultAndTagsMap;
    }

    /**
     * 推导显示规则的结论
     * @param showRuleMap
     * @param showKeysMap
     * @param conclusionRuleMap
     * @return
     */
    public List<String> deduceShowRuleConclusion(Map<Integer,List<Integer>>  showRuleMap,Map<Integer,String[]> showKeysMap,  Map<Integer,ConclusionRuleEx> conclusionRuleMap){
        //有匹配上值显示规则
        List<String> showConclusionList=new ArrayList<>();
        if(null!=showRuleMap && showRuleMap.size()>0){
            //Map<Integer,String[]> showKeysMap = buildAnswerShowKeys(answerResults);
            //多道题的参数，可能采用一个规则去展示Map<规则id,参数数组>
            Map<Integer,String[]> showMap=new IdentityHashMap<>();
            //构建规则和参数的Map
            //TODO: 顺序随机会发生变化
            for (Map.Entry<Integer,List<Integer>> item : showRuleMap.entrySet()) {
                List<Integer> problemIds = item.getValue();
                for (Integer problemId : problemIds) {
                    if (showKeysMap.containsKey(problemId)){
                        showMap.put(item.getKey(),showKeysMap.get(problemId));
                    }
                }
            }

            if(null!=showMap && showMap.size()>0){
                //Map<Integer,String> conclusionRuleMap=conclusionRules.stream().collect(Collectors.toMap(p->p.getId(),p->p.getConclusionContent()));
                for (Map.Entry<Integer,String[]> item : showMap.entrySet()){
                    if(conclusionRuleMap.containsKey(item.getKey())){
                        //格式化其中的参数
                        String formatConclusion = conclusionRuleMap.get(item.getKey()).getConclusionContent();
                        String showConclusion=String.format(formatConclusion,item.getValue());
                        showConclusionList.add(showConclusion);
                    }
                }
            }
        }
        return showConclusionList;
    }

    /**
     * 校验范围规则
     * @param valueRules
     * @param valueAnswerKeys
     * @return
     */
    public Boolean verifyValueRule(List<ValueRule> valueRules,Map<Integer,Double> valueAnswerKeys){
        //没有范围答案
        if(null == valueAnswerKeys && valueAnswerKeys.size()==0){
            return false;
        }
        //没有范围规则
        if(null == valueRules && valueRules.size()==0){
            return true;
        }
        Boolean valueSuccFlag=true;
        //可能有多个值范围，类型有的为统计个数，有的为计算折射率
        for(ValueRule item : valueRules){
            List<Integer> problemIds=item.getProblemIds();
            //4道题的折射率比较
            if(item.getType()==1){
                Double refractionValue = hanlderProblemRefraction(problemIds,valueAnswerKeys);
                if (refractionValue < item.getCountMin() || refractionValue > item.getCountMax()) {    //有一个规则不在范围中
                    valueSuccFlag = false;
                    break;
                }
            }
            //个数值累加的范围比较
            if(item.getType()==2) {
                Double totalValue = statisticProblemsValue(problemIds, valueAnswerKeys);
                if (totalValue < item.getCountMin() || totalValue > item.getCountMax()) {    //有一个规则不在范围中
                    valueSuccFlag = false;
                    break;
                }
            }
            //两题的差值的范围比较
            if(item.getType()==3) {
                Double totalValue = minusProblemsValue(problemIds, valueAnswerKeys);
                if (totalValue < item.getCountMin() || totalValue > item.getCountMax()) {    //有一个规则不在范围中
                    valueSuccFlag = false;
                    break;
                }
            }
        }
        return valueSuccFlag;
    }

    /**
     * 统计所有题目的值
     * @param problemIds
     * @param valueAnswerKeys
     * @return
     */
    public Double statisticProblemsValue(List<Integer> problemIds,Map<Integer,Double> valueAnswerKeys){
        Double total=0.0;
        for(Integer id : problemIds){
            if(valueAnswerKeys.containsKey(id)) {
                total += valueAnswerKeys.get(id);
            }
        }
        return total;
    }

    public Double minusProblemsValue(List<Integer> problemIds,Map<Integer,Double> valueAnswerKeys){
        if(problemIds.size()!=2){
            throw new BusinessException("只允许两题比较差值");
        }
        Double minusValueAbs=0.0;
        Double aValue= valueAnswerKeys.get(problemIds.get(0));
        Double bValue= valueAnswerKeys.get(problemIds.get(1));
        minusValueAbs = Math.abs(aValue -bValue);
        return minusValueAbs;
    }

    /**
     *  校验冲突规则
     * @param answerResults
     * @param conflictRules
     * @return
     */
    @Override
    public List<String> verifyConflictRule(List<AnswerResultHanlder> answerResults, List<ConflictRule> conflictRules) {
        Map<String,String> answerKeys=buildAnswerKeys(answerResults);
        //冲突规则
        Map<String,Integer> ruleKeys= buildConflictRuleKeys(conflictRules);
        List<String> conflictResult=new ArrayList<>();
        for(Map.Entry<String,Integer> item : ruleKeys.entrySet()){
            String rule=item.getKey();
            String[] ruleKeyArr=rule.split("\\|");
            //冲突的前提就是存在A题的某答案，同时存在B题的某答案；
            Boolean succFlag=true;              //假设有冲突
            for (int i=0;i<ruleKeyArr.length;i++){
                if(!answerKeys.containsKey(ruleKeyArr[i])){               //不存在这个答案
                    succFlag= false;
                    break;
                }
            }
            if(succFlag){
                conflictResult.add(rule);
            }
        }
        log.info("有冲突：{}", StringUtils.join(conflictResult,","));
        return conflictResult;
    }


    /**
     * 构建答案key
     * @param answerResults
     * @return
     */
    public Map<String,String> buildAnswerKeys(List<AnswerResultHanlder> answerResults){
        Map<String,String> answerKeyMap=new HashMap<>();
        answerResults.forEach(item->{
            for (int i=0;i<item.getResult().length;i++){
                String answer=item.getResult()[i];
                answerKeyMap.put(item.getProblemId()+"#"+answer,answer);
            }
        });
        return answerKeyMap;
    }

    /**
     * 构建答案key
     * @param answerResults
     * @return
     */
    public Map<String,String> buildAnswerOptionKeys(List<AnswerResultHanlder> answerResults){
        Map<String,String> answerKeyMap=new HashMap<>();
        answerResults.forEach(item->{
            if(item.getValueType()==0 || item.getValueType()==1) {
                for (int i = 0; i < item.getResult().length; i++) {
                    String answer = item.getResult()[i];
                    answerKeyMap.put(item.getProblemId() + "#" + answer, answer);
                }
            }
        });
        return answerKeyMap;
    }

    /**
     * 构建答案的统计值
     * @param answerResults
     * @return
     */
    public Map<Integer,Double> buildAnswerValueKeys(List<AnswerResultHanlder> answerResults){
        Map<Integer,Double> answerKeyMap=new HashMap<>();
        answerResults.forEach(item->{
            if(item.getValueType()==1 || item.getValueType()==2) {           //有可能为1，也有可能为2
                for (int i = 0; i < item.getResult().length; i++) {
                    answerKeyMap.put(item.getProblemId(), item.getValue());     //个数统计
                }
            }
        });
        return answerKeyMap;
    }

    public Map<Integer,String[]> buildAnswerShowKeys(List<AnswerResultHanlder> answerResults){
        Map<Integer,String[]> answerKeyMap=new HashMap<>();
        answerResults.forEach(item->{
            if(item.getValueType()==3) {           //有可能为1，也有可能为2
                answerKeyMap.put(item.getProblemId(), item.getShowValue());     //个数统计
            }
        });
        return answerKeyMap;
    }

    /**
     * 构建结论规则key，结论在前，规则在后
     * @param conclusionRules
     * @return
     */
    public Map<String,Integer> buildConclusionRuleKeys(List<ConclusionRule> conclusionRules){
        Map<String,Integer> ruleKeyMap=new HashMap<>();
        //循环各个规则
        conclusionRules.forEach(item->{
            List<ResultRule> ruleContent=item.getRuleContent();
            //规则关联到了多个题，复合多个题
            ArrayList<ArrayList<String>> problemKeyMap=new ArrayList<>();
            for(int i=0;i<ruleContent.size();i++){
                //题内有多个选项，构造相与的选项
                String[] options=ruleContent.get(i).getOptions();
                ArrayList<String> keys=new ArrayList<>();
                for (int j=0;j<options.length;j++){
                    keys.add(ruleContent.get(i).getProblemId()+"#"+options[j]);
                }
                // 参考：list转为数组
                //String[] keyArr=new String[keys.size()];
                //keys.toArray(keyArr)
                problemKeyMap.add(keys);
            }
            //结构变为，1：A,1:C；5：C；5：D；继续加工笛卡尔积
            ArrayList<String> keyDkrList= CartesianArith.descartes(problemKeyMap);
            for(int k=0;k<keyDkrList.size();k++){
                //String[] dkrKeys=keyDkrList.get(k).split("\\|");
                //ruleKeyMap.put(item.getId(), Arrays.asList(dkrKeys));
                ruleKeyMap.put(keyDkrList.get(k),item.getId());
            }
        });
        return ruleKeyMap;
    }

    //从里面找出选项规则，值范围规则，显示规则等
    public Map<String,Object> buildConclusionRuleKeysEx(List<ConclusionRuleEx> conclusionRules) {
        Map<String,Object> ruleMap=new HashMap<>();
        Map<String,Integer> optionRuleMap = new IdentityHashMap<>();         //选项规则
        Map<Integer,List<ValueRule>> valueRuleMap = new HashMap<>();         //值范围规则
        Map<Integer,List<Integer>> showRuleMap=new HashMap<>();               //显示规则
        //循环多条规则
        conclusionRules.forEach(item->{
            //新的规则
            ResultRuleEx resultRuleEx =item.getRuleContent();
            //有选项的笛卡尔积规则
            //例子：[{"problemId":17,"options":["A","B"]},{"problemId":19,"options":["1.61"]}]
            List<OptionRule> optionContent= resultRuleEx.getOptionRules();
            //有值选项的范围比较规则
            List<ValueRule> valueContent= resultRuleEx.getValueRules();
            //有值选项的范围比较规则
            ShowRule showContent= resultRuleEx.getShowRule();

            if(null!=optionContent && optionContent.size()>0){
                Map<String,Integer> optionMap = buildConclusionOptionRuleKeysEx(optionContent,item.getId());
                optionRuleMap.putAll(optionMap);
            }
            if(null!=valueContent && valueContent.size()>0){
                valueRuleMap.put(item.getId(), valueContent);
            }
            if(null!=showContent){
                showRuleMap.put(item.getId(), showContent.getProblemIds());
            }
        });
        if(optionRuleMap.size()>0){
            ruleMap.put("OptionRules",optionRuleMap);
        }
        if(valueRuleMap.size()>0){
            ruleMap.put("ValueRules",valueRuleMap);
        }
        if(showRuleMap.size()>0){
            ruleMap.put("ShowRules",showRuleMap);
        }
        return ruleMap;
    }

    /**
     * 构建结论规则key，推导在前，规则在后
     * @return
     */
    public Map<String,Integer> buildConclusionOptionRuleKeysEx(List<OptionRule> ruleContent,Integer ruleId){
        Map<String,Integer> ruleKeyMap=new IdentityHashMap<>();
        //规则关联到了多个题，复合多个题
        ArrayList<ArrayList<String>> problemKeyList = new ArrayList<>();
        for (int i = 0; i < ruleContent.size(); i++) {        //循环规则内，每道题内部的或规则
            //单题规则内有多个选项，构造相与的选项
            String[] options = ruleContent.get(i).getOptions();
            ArrayList<String> keys = new ArrayList<>();
            for (int j = 0; j < options.length; j++) {
                keys.add(ruleContent.get(i).getProblemId() + "#" + options[j]);   //比如：形成17#A，17#B
            }
            problemKeyList.add(keys);         //两道题，则有两个对象
        }
        //结构变为，1：A,1:C；5：C；5：D；继续加工笛卡尔积，得出题与题之间的相与的规则
        ArrayList<String> keyDkrList = CartesianArith.descartes(problemKeyList);
        for (int k = 0; k < keyDkrList.size(); k++) {
            //String[] dkrKeys=keyDkrList.get(k).split("\\|");
            //ruleKeyMap.put(item.getId(), Arrays.asList(dkrKeys));
            ruleKeyMap.put(keyDkrList.get(k), ruleId);
        }
        return ruleKeyMap;
    }

     /**
     * 构建结论规则key，结论在前，规则在后
     * @param conclusionRules
     * @return
     */
    public Map<String,Integer> buildConclusionOptionRuleKeys(List<ConclusionRuleEx> conclusionRules){
        Map<String,Integer> ruleKeyMap=new IdentityHashMap<>();
        //循环各个规则
        //例子，两条规则
        //规则Id:8  内容 [{"problemId":17,"options":["A","B"]},{"problemId":19,"options":["1.61"]}]
        //规则Id:9  内容 [{"problemId":12,"options":["A"]},{"problemId":19,"options":["1.67"]}]
        conclusionRules.forEach(item->{
            //新的规则
            ResultRuleEx resultRuleEx =item.getRuleContent();
            //有选项的笛卡尔积规则
            //例子：[{"problemId":17,"options":["A","B"]},{"problemId":19,"options":["1.61"]}]
            List<OptionRule> ruleContent= resultRuleEx.getOptionRules();
            if(null!=ruleContent) {
                //规则关联到了多个题，复合多个题
                ArrayList<ArrayList<String>> problemKeyList = new ArrayList<>();
                for (int i = 0; i < ruleContent.size(); i++) {        //循环规则内，每道题内部的或规则
                    //单题规则内有多个选项，构造相与的选项
                    String[] options = ruleContent.get(i).getOptions();
                    ArrayList<String> keys = new ArrayList<>();
                    for (int j = 0; j < options.length; j++) {
                        keys.add(ruleContent.get(i).getProblemId() + "#" + options[j]);   //比如：形成17#A，17#B
                    }
                    problemKeyList.add(keys);         //两道题，则有两个对象
                }
                //结构变为，1：A,1:C；5：C；5：D；继续加工笛卡尔积，得出题与题之间的相与的规则
                ArrayList<String> keyDkrList = CartesianArith.descartes(problemKeyList);
                for (int k = 0; k < keyDkrList.size(); k++) {
                    //String[] dkrKeys=keyDkrList.get(k).split("\\|");
                    //ruleKeyMap.put(item.getId(), Arrays.asList(dkrKeys));
                    ruleKeyMap.put(keyDkrList.get(k), item.getId());
                }
            }
        });
        //得出如下结果：<"17#A|19#1.61","8"> <"17#B|19#1.61","8"> <"12#A|19#1.67","9">
        return ruleKeyMap;
    }

    /**
     * 构建统计范围规则，规则id在前，范围比较在后
     * @param conclusionRules
     * @return
     */
    public Map<Integer,List<ValueRule>> buildConclusionValueRuleKeys(List<ConclusionRuleEx> conclusionRules){
        Map<Integer,List<ValueRule>> ruleKeyMap=new HashMap<>();
        //循环各个规则
        conclusionRules.forEach(item->{
            //新的规则
            ResultRuleEx resultRuleEx =item.getRuleContent();
            //有值选项的范围比较规则
            List<ValueRule> ruleContent= resultRuleEx.getValueRules();
            if(null!=ruleContent && ruleContent.size()>0) {
                ruleKeyMap.put(item.getId(), ruleContent);
            }
        });
        return ruleKeyMap;
    }

    /**
     * 构建统计范围规则，规则id在前，范围比较在后
     * @param conclusionRules
     * @return
     */
    public Map<Integer,List<Integer>> buildConclusionShowRuleKeys(List<ConclusionRuleEx> conclusionRules){
        Map<Integer,List<Integer>> ruleKeyMap=new HashMap<>();
        //循环各个规则
        conclusionRules.forEach(item->{
            //新的规则
            ResultRuleEx resultRuleEx =item.getRuleContent();
            //有值选项的范围比较规则
            ShowRule ruleContent= resultRuleEx.getShowRule();
            if(null!=ruleContent) {
                ruleKeyMap.put(item.getId(), ruleContent.getProblemIds());
            }
        });
        return ruleKeyMap;
    }


    /**
     * 冲突规则只有A题和B题，不会有C题
     * @param conflictRules
     * @return
     */
    public Map<String,Integer> buildConflictRuleKeys(List<ConflictRule> conflictRules){
        Map<String,Integer> ruleKeyMap=new HashMap<>();
        //循环各个规则
        conflictRules.forEach(item->{
            List<ResultRule> ruleContent=item.getRuleContent();
            //规则关联到了多个题，复合多个题
            ArrayList<ArrayList<String>> problemKeyMap=new ArrayList<>();
            for(int i=0;i<ruleContent.size();i++){
                //题内有多个选项，构造相与的选项
                String[] options=ruleContent.get(i).getOptions();
                ArrayList<String> keys=new ArrayList<>();
                for (int j=0;j<options.length;j++){
                    keys.add(ruleContent.get(i).getProblemId()+"#"+options[j]);
                }
                problemKeyMap.add(keys);
            }
            //结构变为，1：A,1:C；5：C；5：D；继续加工笛卡尔积
            ArrayList<String> keyDkrList= CartesianArith.descartes(problemKeyMap);
            for(int k=0;k<keyDkrList.size();k++){
                ruleKeyMap.put(keyDkrList.get(k),item.getId());
            }
        });
        return ruleKeyMap;
    }

    /**
     * 处理滑块折射率
     * @return
     */
    private Double hanlderProblemRefraction(List<Integer> problemIds,Map<Integer,Double> valueAnswerKeys){
        try {
            if(problemIds.size()!=4){
                throw new BaseException("折射率题目的个数规则配置有问题");
            }
            //TODO:这里写死
            Double leftShortSighted = valueAnswerKeys.get(problemIds.get(0));
            Double leftFlood = valueAnswerKeys.get(problemIds.get(1));
            Double rightShortSighted = valueAnswerKeys.get(problemIds.get(2));
            Double rightFlood = valueAnswerKeys.get(problemIds.get(3));
            Double leftDegree=0.00;
            if(leftShortSighted<=0) {
                leftDegree = leftShortSighted + leftFlood / 2;
            }else {
                leftDegree =leftShortSighted;
            }
            Double rightDegree=0.00;
            if(rightShortSighted<=0) {
                rightDegree = rightShortSighted + rightFlood / 2;
            }else {
                rightDegree = rightShortSighted;
            }
            Double degree=leftDegree>rightDegree?leftDegree:rightDegree;
            Double refraction=degreeToRefraction(degree);
            log.info("计算折射率结果：{}",refraction);
            return refraction;
        }catch (Exception ex){
            throw new BaseException("折射率计算有问题，可能是题目和规则不匹配");
        }
    }

    /**
     * 度数转换成折射率
     * @param degree
     * @return
     */
    private Double degreeToRefraction(Double degree){
        Double refraction=0.00;
        if(degree>=-2.00 && degree<0.00){
            refraction=1.50;
        }else if(degree>=-4.00 && degree<-2.00){
            refraction=1.56;
        }else if(degree>=-6.00 && degree<-4.00){
            refraction=1.61;
        }else if(degree>=-8.00 && degree<-6.00){
            refraction=1.67;
        }else if(degree<-8.00){
            refraction=1.74;
        }else if(degree>=0.00 && degree<2.00){
            refraction=1.50;
        }else if(degree>=2.00 && degree<4.00){
            refraction=1.56;
        }else if(degree>=4.00 && degree<6.00){
            refraction=1.61;
        }else if(degree>=6.00 && degree<8.00){
            refraction=1.67;
        }else if(degree>=8.00){
            refraction=1.74;
        }
        return refraction;
    }
}
